#include <func.h>
#include "client.h"
char* cmd_table[] = { "ls","cd","gets","puts","pwd","remove","mkdir","rmdir","tree" };
int recv_msg(int netfd,char *buf);
int send_msg(int netfd,char *buf);

typedef struct shareRes_s{
    char* cmd;
    char* arg;
    struct sockaddr_in serverAddr;
    char token[2048];
    char user_name[32];
}shareRes_t;

void* threadFunc(void* arg){
      printf("thread create sucessfully\n");
      
      shareRes_t* pshareRes=(shareRes_t*)arg;
      char* pcmd=pshareRes->cmd;
      char* parg=pshareRes->arg;
      
      int client_fd=socket(AF_INET,SOCK_STREAM,0);
      int ret= connect(client_fd,(struct sockaddr*)&pshareRes->serverAddr,sizeof(struct sockaddr));
      ERROR_CHECK(ret,-1,"connect");
      send_msg(client_fd,pshareRes->user_name);
      send_msg(client_fd,pshareRes->token);

      if(strcmp(pcmd,"gets")==0){

          printf("child is going to get a file!\n");
          getsfile(client_fd,parg);
          printf("child gets a file sucessfully!\n");
          printf("child is going to close netfd= %d and exit!\n",client_fd);
          close(client_fd);
          pthread_exit(NULL);

      }//下载
      else if(strcmp(pcmd,"puts")==0){

          printf("child is going to put a file!\n");
          sendFile(client_fd,parg);
          printf("child puts a file sucessfully!\n");
          printf("child is going to close netfd= %d and exit!\n",client_fd);
          close(client_fd);
          pthread_exit(NULL);

      }else{

          printf("The cmd is not 'puts' or 'gets',find the bug please!\n");
          printf("child is going to close netfd= %d and exit!\n",client_fd);
          close(client_fd);
          pthread_exit(NULL);

      }

          pthread_exit(NULL);
}
int is_cmd_legal(char* cmd, char** cmd_table,int len) {

    int i = 0;
    while (i<len) {
        if (strcmp(cmd, cmd_table[i])==0) {
            return 0;
        }
        i++;
    }

    return -1;
}

//分割命令
int cmd_separation(char *cmd_string,char *cmd,char *arg)
{
    int len= SIZE(cmd_table);
    char* p = cmd_string;
    int i = 0;
    while ((*p) != ' ' && (*p) != '\n'&&(*p)!='\0') {//分离出命令存到cmd
        cmd[i] = *p;
        p++;
        ++i;
    }

    int ret1=is_cmd_legal(cmd,cmd_table,len);
    if(ret1==-1)
    {
        return -1;
    }

    if (*p=='\0') {//无参命令
        arg = "\0";
        return 0;
    }
    p++;

    i = 0;
    while (*p != '\0') {
        arg[i++] = *p;
        p++;
    }
    return 0;
}


//接收发出命令后，服务端返回的信息
int recv_msg(int netfd,char *buf)
{
    int length;
    recvn(netfd,&length,sizeof(int));
    recvn(netfd,buf,length);
    return 0;
}

//向客户端发送命令信息
int send_msg(int netfd,char *buf)
{
    int length;
    length = strlen(buf);
    send(netfd,&length,sizeof(int),0);
    send(netfd,buf,length,0);
    return 0;
}

int main(int argc,char *argv[])
{
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd,(struct sockaddr *)&serverAddr, sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"connect");
    
    char cmd_string[100]={0};
    char cmd[10]={0};
    char arg[100]={0};
    char cmd_ret_msg[100]={0};
    char name[20]={0};
    char password[100]={0};
    char isserver_connect[10]={0};
    
    while(1)
    {
        memset(name,0,sizeof(name));
        memset(password,0,sizeof(password));
        printf("请输入用户名:\n");
        scanf("%s",name);
        printf("请输入密码:\n");
        scanf("%s",password);
        int c;
        while((c=getchar())!='\n'&&c!=EOF);
        
        send_msg(sockfd,name);
        send_msg(sockfd,password);
        //传输用户名和密码
        memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
        recv_msg(sockfd,cmd_ret_msg);
        printf("%s\n",cmd_ret_msg);
        //收到返回值
        
        if(strcmp(cmd_ret_msg,"注册成功")==0||strcmp(cmd_ret_msg,"登录成功!")==0)
        {
            memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
            //清除返回值
            //recv_msg(sockfd,cmd_ret_msg);
            //printf("%s",cmd_ret_msg);
            //memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
            //recv_msg(sockfd,cmd_ret_msg);
            //printf("%s",cmd_ret_msg);
            break;
        }
        

    }
    int flag=0;
    while(1)
    {
        memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
        memset(cmd,0,sizeof(cmd));
        memset(arg,0,sizeof(arg));
        fgets(cmd_string,100,stdin);
        
        cmd_string[strcspn(cmd_string,"\n")]='\0';
        
        if(strcmp(cmd_string,"quit")==0)
        {
            break;
        }
        int cmd_ret =cmd_separation(cmd_string,cmd,arg);
        
        if(flag!=-1)

        {
            memset(isserver_connect,0,sizeof(isserver_connect));
            int exit_ret=recv(sockfd,isserver_connect,sizeof(isserver_connect),0);
            if(exit_ret==0)
            {
                printf("服务器已关闭！\n");
                flag=1;
            }
        }
        if(flag==1)
        {
            break;
        }
        if(cmd_ret==-1)
        {
            printf("%s命令错误\n",cmd);
            flag=-1;
            continue;
        }
        flag=0;

        send_msg(sockfd,cmd);
        send_msg(sockfd,arg);

            
            shareRes_t shareRes;
            bzero(&shareRes,sizeof(shareRes_t));
            shareRes.cmd=cmd;
            shareRes.arg=arg;
            shareRes.serverAddr=serverAddr;
            recv_msg(sockfd,shareRes.user_name);
            recv_msg(sockfd,shareRes.token);

        if(strcmp(cmd,"gets")==0)//下载
        {
            int retnum = 0;
            send_msg(sockfd,arg);
            recv(sockfd,&retnum,sizeof(retnum),0);
            if(retnum==-1){
                printf("文件名错误!\n");
                continue;
            }
            printf("找到文件!\n");
            pthread_t tid;
            pthread_create(&tid,NULL,threadFunc,(void*)&shareRes);
        }else if(strcmp(cmd,"puts")==0){

            pthread_t tid;
            pthread_create(&tid,NULL,threadFunc,(void*)&shareRes);
            char md5_str[33];
            ret=Compute_file_md5(arg,md5_str);
            
                
        }
        else
        {
            //如果不是下载命令就打印返回的信息
            recv_msg(sockfd,cmd_ret_msg);
            printf("%s",cmd_ret_msg);
        }
    }
    close(sockfd);
    return 0;
}

